<template>
  <div style="float:left;">
    <el-form>
      <el-row>
        <el-col :span="16">
          <!-- 最上面的选择控件 -->
          <el-select v-model="type" placeholder="请选择组件类型">
            <el-option label="array-table" value="array-table"></el-option>
            <el-option label="输入框" value="input"></el-option>
            <el-option label="计数器" value="input-number"></el-option>
            <el-option label="文本域" value="textarea"></el-option>
            <el-option label="下拉框" value="select"></el-option>
            <el-option label="颜色选择器" value="color-picker"></el-option>
            <el-option label="日期选择器" value="date-picker"></el-option>
            <el-option label="滑块" value="slider"></el-option>
            <el-option label="评分" value="rate"></el-option>
            <el-option label="单选框" value="radio"></el-option>
            <el-option label="复选框" value="checkbox"></el-option>
            <el-option label="上传控件" value="upload"></el-option>
            <el-option label="文本" value="label"></el-option>
            <el-option label="array-tabs" value="array-tabs"></el-option>
          </el-select>
          <el-button type="primary" icon="el-icon-plus" @click="handerClick" circle></el-button>
        </el-col>
      </el-row>
    </el-form>
    <table>
      <tr :key="index" v-for="(item,index) in list">
        <td style="float: left;">
          <!-- 选择的控件遍历 -->
          <el-input v-if="item.btntype !=  'array-table'" placeholder="请输入name" v-model="item.name" style="width:130px"></el-input>
          <el-input v-if="item.btntype !=  'array-table'" placeholder="请输入字段名称" v-model="item.ui.label" style="width:150px"></el-input>
          <el-input v-if="item.btntype ==  'array-table'" placeholder="请输入嵌套表单名称" v-model="item.name" style="width:170px"></el-input>
          <el-select v-model="item.btntype" placeholder="请选择组件类型" disabled style="width:130px">
            <el-option label="输入框" value="input"></el-option>
            <el-option label="计数器" value="input-number"></el-option>
            <el-option label="文本域" value="textarea"></el-option>
            <el-option label="下拉框" value="select"></el-option>
            <el-option label="颜色选择器" value="color-picker"></el-option>
            <el-option label="日期选择器" value="date-picker"></el-option>
            <el-option label="滑块" value="slider"></el-option>
            <el-option label="评分" value="rate"></el-option>
            <el-option label="单选框" value="radio"></el-option>
            <el-option label="复选框" value="checkbox"></el-option>
            <el-option label="上传控件" value="upload"></el-option>
            <el-option label="文本" value="label"></el-option>
            <el-option label="array-table" value="array-table"></el-option>
            <el-option label="array-tabs" value="array-tabs"></el-option>
          </el-select>
          <el-button type="primary" icon="el-icon-setting" @click="haderSetting(item)" circle></el-button>
          <el-button type="danger" icon="el-icon-close" @click="handerDelete(index)" circle></el-button>
          <!-- 嵌套控件的选择控件 -->
          <el-select v-if="item.btntype ===  'array-table'" v-model="typeobject" placeholder="请选择组件类型" style="width:150px">
            <el-option label="输入框" value="input"></el-option>
            <el-option label="计数器" value="input-number"></el-option>
            <el-option label="文本域" value="textarea"></el-option>
            <el-option label="下拉框" value="select"></el-option>
            <el-option label="颜色选择器" value="color-picker"></el-option>
            <el-option label="日期选择器" value="date-picker"></el-option>
            <el-option label="滑块" value="slider"></el-option>
            <el-option label="评分" value="rate"></el-option>
            <el-option label="单选框" value="radio"></el-option>
            <el-option label="复选框" value="checkbox"></el-option>
            <el-option label="上传控件" value="upload"></el-option>
            <el-option label="文本" value="label"></el-option>
          </el-select>
          <el-button v-if="item.btntype ===  'array-table'" type="primary" icon="el-icon-plus" @click="handerObjectClick(index)" circle></el-button>

          <table v-if="item.btntype ===  'array-table'" style=" border:solid #cccccc 1px;">
            <tr :key="indexx" v-for="(info,indexx) in item.items.propertieslist">
              <td>
                <!-- 嵌套控件遍历 -->
                <el-input placeholder="请输入name" v-model="info.name" style="width:130px"></el-input>
                <el-input placeholder="请输入字段名称" v-model="info.ui.label" style="width:150px"></el-input>
                <el-select v-model="info.btntype" placeholder="请选择组件类型" disabled style="width:130px">
                  <el-option label="输入框" value="input"></el-option>
                  <el-option label="计数器" value="input-number"></el-option>
                  <el-option label="文本域" value="textarea"></el-option>
                  <el-option label="下拉框" value="select"></el-option>
                  <el-option label="颜色选择器" value="color-picker"></el-option>
                  <el-option label="日期选择器" value="date-picker"></el-option>
                  <el-option label="滑块" value="slider"></el-option>
                  <el-option label="评分" value="rate"></el-option>
                  <el-option label="单选框" value="radio"></el-option>
                  <el-option label="复选框" value="checkbox"></el-option>
                  <el-option label="上传控件" value="upload"></el-option>
                  <el-option label="文本" value="label"></el-option>
                </el-select>
                <el-button type="primary" icon="el-icon-setting" @click="handerSettingObject(info)" circle></el-button>
                <el-button type="danger" icon="el-icon-close" @click="handerDeleteObject(index,indexx)" circle></el-button>
              </td>
            </tr>
          </table>
        </td>
      </tr>
    </table>
    表名：<el-input placeholder="请输入表名" v-model="formSchema.tablename" style="width:130px"></el-input>
    <el-dialog title="提示" :visible.sync="centerDialogVisible" width="50%" top="3vh" center>
      <inputItem v-if="showcomponent == 1" :item="item" @hclick="handerDeleteSet">
      </inputItem>
      <inputnumberitem v-if="showcomponent == 2" :item="item" @hclick="handerDeleteSet">
      </inputnumberitem>
      <textareaitem v-if="showcomponent == 3" :item="item" @hclick="handerDeleteSet">
      </textareaitem>
      <selectitem v-if="showcomponent == 4" :item="item" @hclick="handerDeleteSet">
      </selectitem>
      <colorpickitem v-if="showcomponent == 5" :item="item" @hclick="handerDeleteSet">
      </colorpickitem>
      <datepickitem v-if="showcomponent == 6" :item="item" @hclick="handerDeleteSet">
      </datepickitem>
      <slideritem v-if="showcomponent == 7" :item="item" @hclick="handerDeleteSet">
      </slideritem>
      <rateitem v-if="showcomponent == 8" :item="item" @hclick="handerDeleteSet">
      </rateitem>
      <radioitem v-if="showcomponent == 9" :item="item" @hclick="handerDeleteSet">
      </radioitem>
      <checkboxitem v-if="showcomponent == 10" :item="item" @hclick="handerDeleteSet">
      </checkboxitem>
      <labelitem v-if="showcomponent == 11" :item="item" @hclick="handerDeleteSet">
      </labelitem>
      <uploaditem v-if="showcomponent == 12" :item="item" @hclick="handerDeleteSet">
      </uploaditem>
    </el-dialog>
    <el-button type="primary" @click="handerJson">创建表</el-button>
  </div>

</template>

<script>
import Vue from "vue";
import axios from "axios";
import inputItem from "@/components/inputItem";
import inputnumberitem from "@/components/inputnumberitem";
import textareaitem from "@/components/textareaitem";
import selectitem from "@/components/selectitem";
import colorpickitem from "@/components/colorpickitem";
import datepickitem from "@/components/datepickitem";
import slideritem from "@/components/slideritem";
import rateitem from "@/components/rateitem";
import radioitem from "@/components/radioitem";
import checkboxitem from "@/components/checkboxitem";
import labelitem from "@/components/labelitem";
import uploaditem from "@/components/uploaditem";

export default {
  name: "HelloWorld",
  data() {
    return {
      schematype: "2", //用于判断当前是新增还是更新操作 1:新增 2:编辑
      sql: "", //操作表的sql
      arraysql: "", //操作从表的sql
      centerDialogVisible: false, //是否显示详情
      type: "", //控件类型
      typeobject: "", //嵌套控件类型
      item: {}, //用于设置 传过去的对象
      showcomponent: 0, //用于显示哪个组件
      list: [], //当前页面上选择的list集合
      formSchema: {
        //schema模板
        tablename: "",
        tablesqlname: "",
        type: "object",
        ui: {
          widgetConfig: {
            layout: "h"
          }
        },
        properties: {}
      }
    };
  },
  methods: {
    //添加表单
    handerClick: function() {
      this.showcomponent = 0;
      this.AddJson(this.list, this.type);
    },
    //嵌套添加表单
    handerObjectClick(index) {
      this.AddJson(this.list[index].items.propertieslist, this.typeobject);
    },
    //给表单动态添加数据(包含嵌套) listjson：需要添加的集合   type:添加的控件类型
    AddJson(listjson, type) {
      if (type == "input") {
        listjson.push({
          name: "",
          btntype: type,
          type: "string",
          ui: {
            label: "",
            disabled: false,
            widgetConfig: {
              trim: false,
              type: "text",
              compound: { prependLabel: "", appendLabel: "" }
            },
            readonly: false,
            placeholder: ""
          },
          rules: {
            required: {
              value: false,
              errMsg: ""
            },
            pattern: {
              value: "",
              errMsg: ""
            }
          },
          value: ""
        });
      } else if (type == "input-number") {
        listjson.push({
          name: "",
          type: "number",
          btntype: type,
          ui: {
            label: "",
            widget: "input-number",
            widgetConfig: { step: 0 },
            disabled: false,
            readonly: false
          }
        });
      } else if (type == "textarea") {
        listjson.push({
          name: "",
          type: "string",
          btntype: type,
          ui: {
            widgetConfig: { rows: 2 },
            label: "",
            widget: "textarea"
          },
          value: ""
        });
      } else if (type == "select") {
        listjson.push({
          name: "",
          type: "string",
          btntype: type,
          ui: {
            label: "",
            widget: "select",
            widgetConfig: {
              multiple: false,
              filterable: true,
              placeholder: "",
              enumSource: []
            },
            disabled: false,
            readonly: false
          }
        });
      } else if (type == "color-picker") {
        listjson.push({
          name: "",
          type: "string",
          btntype: type,
          ui: {
            widgetConfig: {},
            label: "",
            widget: "color-picker",
            readonly: false
          },
          value: ""
        });
      } else if (type == "date-picker") {
        listjson.push({
          name: "",
          type: "string",
          btntype: type,
          ui: {
            widget: "date-picker",
            disabled: false,
            readonly: false,
            placeholder: ""
          },
          value: ""
        });
      } else if (type == "slider") {
        listjson.push({
          name: "",
          type: "number",
          btntype: type,
          ui: {
            widgetConfig: { min: 0, max: 1000, step: 0 },
            label: "",
            widget: "slider",
            disabled: false,
            readonly: false
          },
          value: 0
        });
      } else if (type == "rate") {
        listjson.push({
          name: "",
          type: "number",
          btntype: type,
          ui: {
            widgetConfig: { max: 5, allowHalf: false },
            label: "",
            widget: "rate",
            disabled: false,
            readonly: false
          },
          value: 0
        });
      } else if (type == "radio") {
        listjson.push({
          name: "",
          type: "boolean",
          btntype: type,
          ui: {
            label: "",
            widgetConfig: {
              enumSource: []
            }
          }
        });
      } else if (type == "checkbox") {
        listjson.push({
          name: "",
          type: "array",
          btntype: type,
          ui: {
            label: "",
            widget: "checkbox",
            widgetConfig: {
              selectAll: true,
              enumSource: []
            },
            disabled: false
          }
        });
      } else if (type == "label") {
        listjson.push({
          name: "",
          type: "string",
          btntype: type,
          value: "",
          ui: {
            widget: "label",
            widgetConfig: {
              multiLine: true
            }
          }
        });
      } else if (type == "upload") {
        listjson.push({
          name: "",
          type: "array",
          btntype: type,
          ui: {
            widget: "upload",
            widgetConfig: {
              uploadUrl: "",
              resField: "data",
              fileNameField: "url",
              showFileList: true,
              fileField: "file"
            }
          }
        });
      } else if (type == "array-table") {
        listjson.push({
          name: "",
          type: "array",
          btntype: type,
          ui: {
            widget: "array-table",
            label: "",
            widgetConfig: {
              disableAdd: false,
              addTxt: "增加",
              delAllTxt: "删除全部"
            }
          },
          items: {
            type: "object",
            properties: {},
            propertieslist: [],
            tablename: ""
          }
        });
      }
    },
    //删除表单
    handerDelete: function(index) {
      this.list.splice(index, 1);
    },
    //删除嵌套
    handerDeleteObject: function(index, indexobject) {
      this.list[index].items.propertieslist.splice(indexobject, 1);
    },
    //设置内容
    haderSetting: function(item) {
      this.centerDialogVisible = true;
      this.item = item;
      this.SetHide(item);
    },
    //设置嵌套表单内容
    handerSettingObject(info) {
      this.centerDialogVisible = true;
      this.item = info;
      this.SetHide(info);
    },
    //嵌套或者非嵌套设置隐藏属性值
    SetHide(info) {
      if (info.btntype == "input") {
        this.showcomponent = 1;
      } else if (info.btntype == "input-number") {
        this.showcomponent = 2;
      } else if (info.btntype == "textarea") {
        this.showcomponent = 3;
      } else if (info.btntype == "select") {
        this.showcomponent = 4;
      } else if (info.btntype == "color-picker") {
        this.showcomponent = 5;
      } else if (info.btntype == "date-picker") {
        this.showcomponent = 6;
      } else if (info.btntype == "slider") {
        this.showcomponent = 7;
      } else if (info.btntype == "rate") {
        this.showcomponent = 8;
      } else if (info.btntype == "radio") {
        this.showcomponent = 9;
      } else if (info.btntype == "checkbox") {
        this.showcomponent = 10;
      } else if (info.btntype == "label") {
        this.showcomponent = 11;
      } else if (info.btntype == "upload") {
        this.showcomponent = 12;
      }
    },
    //生成json
    handerJson: function() {
      this.formSchema.properties = {};
      //将表单的值绑定到schema里
      this.list.forEach((item, index) => {
        Vue.set(this.formSchema.properties, item.name, item);
      });
      //将表单的值绑定到schema里 properties 跟propertieslist 里面的值不一样 格式也不一样
      //properties 是用于插入schema propertieslist 是主要是方便取值遍历sql语句
      this.list.forEach(item => {
        if (item.btntype == "array-table") {
          item.items.properties = {};
          item.items.propertieslist.forEach((info, index) => {
            Vue.set(item.items.properties, info.name, info);
          });
        }
      });

      //中文转字母的表名
      this.formSchema.tablesqlname = this.formSchema.tablename + "1";
      //var guid = this.uuid();
      var urlid = "40584537-0341-4d61-82fb-656f412b94bc";
      var url = "/api/schemaList?id=eq." + urlid;
      //新增模式
      if (this.schematype == "1") {
        //查询主表名是否存在
        this.FindTable(this.formSchema.tablesqlname).then(res => {
          if (res.length > 0) {
            //如果表名存在重新生成表名
            this.formSchema.tablesqlname += new Date().getTime();
          }
          //循环主表 遍历 sql  create的sql语句
          this.sql = "";
          this.sql +=
            "create table " +
            this.formSchema.tablesqlname +
            " ( id varchar(100) not null PRIMARY KEY,";
          //主表循环 去除 array-table 遍历主表 拼接sql
          var farrytablelist = this.list.filter(
            i => i.btntype != "array-table"
          );
          farrytablelist.forEach((element, index) => {
            this.sql += element.name + " " + this.ConventType(element.btntype);
            if (index != farrytablelist.length - 1) {
              this.sql += ",";
            }
          });
          this.sql += ");";
          //从表循环 获取不是array-table 的集合
          this.arraysql = "";
          var arrytablelist = this.list.filter(i => i.btntype == "array-table");
          if (arrytablelist.length == 0) {
            //如果没有从表，主表直接插入
            console.log("需要执行的sql:" + this.sql);
            this.ExcuSql(urlid, url);
            return;
          } else {
            //开始遍历所有从表
            arrytablelist.forEach((element, index) => {
              //所有的从表表名不需要再去检查是否存不在存在，因为从表表名是根据主表来的，主表已经检查过是否存在，所以从表必定唯一
              element.items.tablename = this.formSchema.tablesqlname + + new Date().getTime();;
              this.arraysql +=
                "create table " +
                element.items.tablename +
                " ( id varchar(100) not null PRIMARY KEY, " +
                this.formSchema.tablesqlname +
                "id  varchar(100) not null,";
              //开始遍历从表里的具体字段 拼接sql
              element.items.propertieslist.forEach((info, infoindex) => {
                this.arraysql +=
                  info.name + " " + this.ConventType(info.btntype);
                if (infoindex != element.items.propertieslist.length - 1) {
                  this.arraysql += ",";
                }
              });
              this.arraysql += ");";
              if (index == arrytablelist.length - 1) {
                //执行到最后一条
                //主表跟从表，一起拼接 最终要插入数据库的值
                this.sql += this.arraysql;
                console.log("sql语句：" + this.sql);
                this.ExcuSql(urlid, url);
                return;
              }
            });
          }
        });
      } else {
        //编辑模式
        //编辑模式1:先更改主表 add drop 列名
        //编辑模式2：判断从表是否存在，若存在 跟第一步一样 若不存在 新增create table
        //编辑模式3: 删除此次页面上删除的从表
        //操作主表
        console.log("主表名称"+this.formSchema.tablesqlname);
        this.FindTable(this.formSchema.tablesqlname).then(res => {
         // debugger;
          this.sql = "";
          //获取需要更新操作的字段 主表  需要新增的字段
          var aa = this.list
            .filter(i => i.btntype != "array-table");
          this.list
            .filter(i => i.btntype != "array-table")
            .forEach((element, index) => {
              //debugger;
              var a = res.find(i => i.column_name == element.name);
              if (a == undefined && element.name != "id") {
                this.sql +=
                  "ALTER TABLE " +
                  this.formSchema.tablesqlname +
                  " ADD " +
                  element.name +
                  " " +
                  this.ConventType(element.btntype) +
                  ";  ";
              }
            });
          //获取需要更新操作的字段 主表  需要删除的字段
          res
            .filter(i => i.btntype != "array-table")
            .forEach((element, index) => {
              var a = this.list.find(i => i.name == element.column_name);
              if (a == undefined && element.column_name != "id") {
                this.sql +=
                  "ALTER TABLE " +
                  this.formSchema.tablesqlname +
                  " DROP " +
                  element.column_name +
                  " ;  ";
              }
            });
          //主表操作结束
          //操作从表
          var arrytablelist = this.list.filter(i => i.btntype == "array-table");
          if (arrytablelist.length == 0) {
            //如果没有从表，主表直接更新
            console.log("需要更新主表的sql:" + this.sql);
            this.ExcuSql(urlid, url);
            return;
          } else {
            this.arraysql = "";
            arrytablelist.forEach((element, index) => {
              //如果是新增的从表，需要给他生成表名
              if(element.items.tablename == ""){
                element.items.tablename =
                    this.formSchema.tablesqlname + new Date().getTime();
              }
              //判断从表是否存在
              this.FindTable(element.items.tablename).then(resi => {
                //debugger;
                if (resi.length > 0) {
                  //表如果存在
                  //从表获取需要更新操作的字段 主表  需要新增的字段
                  element.items.propertieslist.forEach((info, index) => {
                    //debugger;
                    var a = resi.find(i => i.column_name == info.name);
                    if (a == undefined && info.name != "id" &&  info.name != this.formSchema.tablesqlname + "id") {
                      this.arraysql +=
                        "ALTER TABLE " +
                        element.items.tablename +
                        " ADD " +
                        info.name +
                        " " +
                        this.ConventType(info.btntype) +
                        ";  ";
                    }
                  });
                  //获取需要更新操作的字段 主表  需要删除的字段
                  resi.forEach((info, index) => {
                    //debugger;
                    var a = element.items.propertieslist.find(
                      i => i.name == info.column_name
                    );
                    if (
                      a == undefined &&
                      info.column_name != this.formSchema.tablesqlname + "id" &&
                      info.column_name != "id"
                    ) {
                      this.arraysql +=
                        "ALTER TABLE " +
                        element.items.tablename +
                        " DROP " +
                        info.column_name +
                        " ;  ";
                    }
                  });
                } else {
                  element.items.tablename =
                    this.formSchema.tablesqlname + new Date().getTime();
                  this.arraysql +=
                    "create table " +
                    element.items.tablename +
                    " ( id varchar(100) not null PRIMARY KEY, " +
                    this.formSchema.tablesqlname +
                    "id  varchar(100) not null,";
                  //开始遍历从表里的具体字段 拼接sql
                  element.items.propertieslist.forEach((info, infoindex) => {
                    this.arraysql +=
                      info.name + " " + this.ConventType(info.btntype);
                    if (infoindex != element.items.propertieslist.length - 1) {
                      this.arraysql += ",";
                    }
                  });
                  this.arraysql += ");";
                }
                if (index == arrytablelist.length - 1) {
                  // debugger;
                  //执行到最后一条
                  //主表跟从表，一起拼接 最终要插入数据库的值
                  this.sql += this.arraysql;
                  console.log("sql语句：" + this.sql);
                  this.ExcuSql(urlid, url);
                  return;
                }
              });
            });
          }
        });
      }
    },
    //查看表名是否存在
    FindTable: function(tablename) {
      return new Promise((resolve, reject) => {
        axios
          .post("http://localhost:3000/rpc/key_customers", {
            tablename: tablename
          })
          .then(res => {
            resolve(res.data);
          })
          .catch(function(error) {
            reject(error);
          });
      });
    },
    //保存schema
    SaveScheme: function(urlid, url) {
      //保存schema json
      axios
        .put(url, {
          formartlist: this.list,
          ncschema: this.formSchema,
          createtime: new Date(),
          tablecname: this.formSchema.tablename,
          tablename: this.formSchema.tablename,
          id: urlid
        })
        .then(function(response) {
          console.log("schema成功保存到数据库");
        });
    },
    //执行sql语句
    ExcuSql(urlid, url) { 
      var $this = this;
      axios
        .post("http://localhost:3000/rpc/testfunction", {
          userinfo: "admin",
          tablecname: this.formSchema.tablename,
          tablename: this.formSchema.tablesqlname,
          sqlm: this.sql,
          typet: this.schematype == "1" ? "create" : "alter"
        })
        .then(function(response) { 
          //插入数据库成功之后修改schema
          $this.SaveScheme(urlid, url);
        });
    },
    //关闭设置
    handerDeleteSet: function() {
      this.centerDialogVisible = false;
      this.showcomponent = 0;
    },
    ConventType: function(type) {
      switch (type) {
        case "input-number":
          return "integer";
          break;
        case "date-picker":
          return "timestamp";
          break;
        case "textarea":
          return "TEXT";
          break;
        case ("slider", "rate"):
          return "decimal";
          break;
        case "object":
          return "object";
          break;
        default:
          return "VARCHAR (500)";
          break;
      }
    }
  },
  components: {
    inputItem,
    inputnumberitem,
    textareaitem,
    selectitem,
    colorpickitem,
    datepickitem,
    slideritem,
    rateitem,
    radioitem,
    checkboxitem,
    labelitem,
    uploaditem
  },
  beforeCreate: function() {
    axios
      .get("/api/schemaList")
      .then(res => {
        this.formSchema.tablename = res.data[0].ncschema.tablename;
        this.list = res.data[0].formartlist;
      })
      .catch(function(error) {
        console.log(11 + error);
      });
  }
};
</script>